package com.liao.ticket.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.liao.ticket.common.exception.ErrorCode;
import com.liao.ticket.dao.mapper.SeatMapper;
import com.liao.ticket.dao.pojo.Flight;
import com.liao.ticket.dao.pojo.Seat;
import com.liao.ticket.service.FlightService;
import com.liao.ticket.service.SeatService;
import com.liao.ticket.util.CheckPowerUtils;
import com.liao.ticket.vo.Result;
import com.liao.ticket.vo.params.SeatParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class SeatServiceImpl implements SeatService {
    @Autowired
    private SeatMapper seatMapper;

    @Autowired
    private FlightService flightService;

    @Override
    public Seat selectOneById(Long id) {
        if (id == null) {
            return null;
        }
        return seatMapper.selectById(id);
    }

    @Override
    public List<Seat> selectListByFid(Long id) {
        if (id == null) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<Seat> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Seat::getFlightId, id);
        return seatMapper.selectList(wrapper);
    }

    @Override
    public Seat addOne(Seat seat) {
        seat.setId(null);
        Seat check = new Seat();
        check.setId(null);
        if (check.equals(seat)) {
            return null;
        }
        if(selectCountByFidAndNoType(seat.getFlightId(),seat.getType()) > 0){
            return null;
        }
        seatMapper.insert(seat);
        return seat;
    }

    @Override
    public Integer updateOneById(Seat seat) {
        if (seat.getId() == null) {
            return 0;
        }
        Seat check = new Seat();
        check.setId(seat.getId());
        if (check.equals(seat)) {
            return 0;
        }
        return seatMapper.updateById(seat);
    }

    @Override
    public Integer deleteOneById(Long id) {
        if (id == null) {
            return 0;
        }
        return seatMapper.deleteById(id);
    }

    @Override
    public Integer deleteListByFid(Long id) {
        if (id == null) {
            return 0;
        }
        LambdaQueryWrapper<Seat> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Seat::getFlightId, id);
        return seatMapper.delete(wrapper);
    }

    @Override
    public Seat selectOneByIdAndFid(Long seatId, Long flightId) {
        LambdaQueryWrapper<Seat> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Seat::getId, seatId).eq(Seat::getFlightId, flightId);
        return seatMapper.selectOne(wrapper);
    }

    @Override
    public Result save(SeatParams seatParams) {
        if(!check(seatParams.getFlightId())){
            return Result.fail(ErrorCode.FLIGHT_SEAT_UPDATE_ERROR);
        }
        if (seatParams.getFlightId() == null) {
            return Result.fail(ErrorCode.FLIGHT_SEAT_ADD_PARAMS_FAIL);
        }
        Seat seat = new Seat();
        seat.setType(seatParams.getType());
        seat.setFlightId(seatParams.getFlightId());
        seat.setNum(seatParams.getNum());
        seat.setPrice(seatParams.getPrice());
        return Result.success(addOne(seat));
    }

    @Override
    public Result updateOneByIdAndFid(SeatParams seatParams) {
        if(!check(seatParams.getFlightId())){
            return Result.fail(ErrorCode.FLIGHT_SEAT_UPDATE_ERROR);
        }
        if (seatParams.getId() == null || seatParams.getFlightId() == null) {
            return Result.fail(ErrorCode.FLIGHT_SEAT_UPDATE_PARAMS_FAIL);
        }
        if(selectCountByFidAndNoType(seatParams.getFlightId(),seatParams.getType()) > 0){
            return Result.fail(ErrorCode.FLIGHT_SEAT_UPDATE_ERROR);
        }
        Seat seat = new Seat();
        seat.setNum(seatParams.getNum());
        seat.setPrice(seatParams.getPrice());
        seat.setType(seatParams.getType());
        LambdaQueryWrapper<Seat> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Seat::getFlightId, seatParams.getFlightId()).eq(Seat::getId, seatParams.getId());
        return Result.success(seatMapper.update(seat, wrapper));
    }

    @Override
    public Result deleteOneByIdAndFid(SeatParams seatParams) {
        if(!check(seatParams.getFlightId())){
            return Result.fail(ErrorCode.FLIGHT_SEAT_UPDATE_ERROR);
        }
        if (seatParams.getId() == null || seatParams.getFlightId() == null) {
            return Result.fail(ErrorCode.FLIGHT_SEAT_UPDATE_PARAMS_FAIL);
        }
        LambdaQueryWrapper<Seat> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Seat::getFlightId, seatParams.getFlightId()).eq(Seat::getId, seatParams.getId());
        return Result.success(seatMapper.delete(wrapper));
    }

    private Boolean check(Long fid) {
        Long mid ;
        if (!((mid = CheckPowerUtils.getMid(0)) != null || (mid = CheckPowerUtils.getMid(30)) != null)) {
            return false;
        }
        if(mid != 0){
            Flight flight = flightService.selectOneByFidAndMid(fid, mid);
            if (flight == null) {
                return false;
            }
        }
        return true;
    }

    private Integer selectCountByFidAndNoType(Long id, Integer type) {
        LambdaQueryWrapper<Seat> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Seat::getFlightId, id).eq(Seat::getType, type);
        return seatMapper.selectCount(wrapper);
    }

}
